package com.example.localinnerclass;

import java.util.concurrent.atomic.AtomicInteger;

class ClassWithStaticMember {
    public static Object staticObj = new Object();
    public static Object getStaticObj(){
        return staticObj;
    }
}

public class OuterClass {

    private String message = "hello, world";

    public void doSomething(){

        int localIntVariable = 10;

        // 局部内部类不能使用private等访问修饰符进行修饰，也不能声明为static
        // 局部内部类可以使用继承和实现接口
        class LocalInnerClass extends ClassWithStaticMember{
            static int anInt = 0; // 编译错误
            static final int anInt2 = 0; // OK
            int anInt3; // OK

            public static void staticMethod(){
                System.out.println("这是在LocalInnerClass的静态方法中输出的内容");
            } // 编译报错

            static {
                System.out.println("这是在LocalInnerClass的静态代码块中输出的内容");
            } // 编译报错

            public void instanceMethod(){
                // 定义在外部类的实例方法中的局部内部类和成员内部类一样，也可以使用“外部类.this”来访问外部类的实例
                System.out.println(OuterClass.this.message);

                // 局部内部类可以访问外面doSomething()方法中定义的局部变量localIntVariable
                int int_value = localIntVariable;
                System.out.println(int_value);

                //localIntVariable = 10; // 错误，不能修改外部类中的局部变量
            }

            private String returnString(){
                return "this is a private method";
            }

        }

        // 创建局部内部类的实例
        LocalInnerClass localInnerClass = new LocalInnerClass();
        localInnerClass.instanceMethod();
        // 在这里，可以无视访问修饰符，直接访问局部内部类中的实例变量
        System.out.println(localInnerClass.anInt3);
        // 在这里，可以无视访问修饰符，直接调用局部内部类中的实例方法
        System.out.println(localInnerClass.returnString());

        LocalInnerClass.staticMethod();
    }

    public static void staticMethod(){
        int localInt = 100;
        AtomicInteger atomicInteger = new AtomicInteger(localInt);

        class LocalInnerClassInStaticMethod{

            static String msg = "这是定义在静态方法中的局部内部类中的[静态变量]";
            static {
                System.out.println("这是定义在静态方法中的局部内部类的[静态代码块]中输出的内容");
            }

            private void doSomething(){
                // 可以访问局部变量
                System.out.println(localInt);

                // 不能非局部变量重新赋值
                // localInt = 10;

                atomicInteger.addAndGet(10);
                System.out.println(atomicInteger.get());

                // 定义在外部类非实例方法中的局部内部类不能用“外部类.this”的方法引用外部类的实例
                // OuterClass that = OuterClass.this; // 编译错误,'com.example.localinnerclass.OuterClass.this' cannot be referenced from a static context
            }
        }

        // 和成员内部类一样，只有在实例化内部类对象或者访问它的静态成员的时候才会加载并初始化内部类
        // new LocalInnerClassInStaticMethod();
        // System.out.println(LocalInnerClassInStaticMethod.msg);
    }

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        outerClass.doSomething();

        staticMethod();
    }
}
